/**
 * Copyright 2020 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <iostream>
#include <memory>
#include "src/common/log_adapter.h"
#include "common/common_test.h"
#include "src/common/file_utils.h"
#include "nnacl/fp32/deconv_fp32.h"
#include "nnacl/op_base.h"
#include "src/litert/tensor_category.h"
#include "nnacl/nnacl_manager.h"

namespace mindspore {
class TestDeConvolutionFp32 : public mindspore::CommonTest {
 public:
  TestDeConvolutionFp32() = default;
};

TEST_F(TestDeConvolutionFp32, DeConvWeightC4x4Pack1) {
  float in[] = {0.43005997,  -0.01335099, -0.43214464, -0.2569654,  -0.14664753, -0.09249142, 0.42330834,  0.17678244,
                -0.26901904, 0.29920393,  -0.25139654, 0.04580693,  0.08898365,  -0.29335496, 0.1332809,   0.06561925,
                0.50099367,  -0.45963442, -0.17191549, -0.1517635,  -0.54385597, 0.20007996,  0.3174582,   -0.13803318,
                -0.10295965, 0.03531377,  -0.05687982, 0.09801699,  -0.1504936,  0.27094424,  -0.15454058, 0.25500196,
                0.03428256,  0.1711275,   -0.28639716, 0.05972834,  0.1301975,   0.09662235,  -0.26297596, 0.25723842,
                0.37723106,  -0.49640322, 0.21951586,  -0.25885767, -0.44244745, 0.04153876,  0.41899854,  0.07920247,
                0.31681255,  0.3300002,   0.23956111,  0.13012694,  0.26047292,  0.0851135,   -0.185474,   0.306445,
                0.20750166,  -0.13887969, -0.15064844, -0.08100204, 0.08206631,  0.3151005,   0.26807567,  -0.6340778,
                0.1019667,   0.14200483,  -0.56623703, 0.47877932,  0.13249867,  0.3862773,   0.7469436,   0.14524518,
                0.42495733,  0.08011179,  0.19647601,  -0.03030056, 0.12770538,  -0.32460797, -0.2103409,  0.33223677,
                -0.47110182, -0.5424416,  0.18340437,  0.3781465,   0.04931778,  0.17888185,  0.04547426,  -0.01483545,
                0.29989168,  0.12018301,  0.00213889,  0.21470474,  -0.4031554,  -0.10013647, -0.12780161, -0.28953925,
                0.05002394,  0.5460746,   -0.7209624,  0.32692385,  -0.09215609, -0.07226299, 0.47478926,  -0.6297518,
                0.22869332,  -0.33726704, -0.24732,    0.07623845,  0.38042688,  -0.18950662, -0.16825019, 0.49407697,
                -0.10242693, 0.59533256,  -0.11732046, 0.7062394,   0.35063574,  -0.17253993, -0.14738934, 0.26435736};
  float co[] = {
    0.43005997,  -0.01335099, -0.43214464, -0.2569654,  -0.10295965, 0.03531377,  -0.05687982, 0.09801699,  0.31681255,
    0.3300002,   0.23956111,  0.13012694,  0.42495733,  0.08011179,  0.19647601,  -0.03030056, 0.05002394,  0.5460746,
    -0.7209624,  0.32692385,  0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.42330834,  0.17678244,  -0.26901904, 0.29920393,
    -0.15454058, 0.25500196,  0.03428256,  0.1711275,   -0.185474,   0.306445,    0.20750166,  -0.13887969, -0.2103409,
    0.33223677,  -0.47110182, -0.5424416,  0.47478926,  -0.6297518,  0.22869332,  -0.33726704, 0.000,       0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.08898365,  -0.29335496, 0.1332809,   0.06561925,  0.1301975,   0.09662235,  -0.26297596, 0.25723842,
    0.08206631,  0.3151005,   0.26807567,  -0.6340778,  0.04931778,  0.17888185,  0.04547426,  -0.01483545, 0.38042688,
    -0.18950662, -0.16825019, 0.49407697,  0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       -0.17191549, -0.1517635,  -0.54385597,
    0.20007996,  0.21951586,  -0.25885767, -0.44244745, 0.04153876,  -0.56623703, 0.47877932,  0.13249867,  0.3862773,
    0.00213889,  0.21470474,  -0.4031554,  -0.10013647, -0.11732046, 0.7062394,   0.35063574,  -0.17253993, 0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       -0.14664753, -0.09249142, 0.000,       0.000,       -0.1504936,  0.27094424,  0.000,
    0.000,       0.26047292,  0.0851135,   0.000,       0.000,       0.12770538,  -0.32460797, 0.000,       0.000,
    -0.09215609, -0.07226299, 0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       -0.25139654, 0.04580693,
    0.000,       0.000,       -0.28639716, 0.05972834,  0.000,       0.000,       -0.15064844, -0.08100204, 0,
    0,           0.18340437,  0.3781465,   0.000,       0.000,       -0.24732,    0.07623845,  0.000,       0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       0.000,       0.50099367,  -0.45963442, 0.000,       0.000,       0.37723106,  -0.49640322,
    0.000,       0.000,       0.1019667,   0.14200483,  0.000,       0.000,       0.29989168,  0.12018301,  0.000,
    0.000,       -0.10242693, 0.59533256,  0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.3174582,
    -0.13803318, 0.000,       0.000,       0.41899854,  0.07920247,  0.000,       0.000,       0.7469436,   0.14524518,
    0.000,       0.000,       -0.12780161, -0.28953925, 0.000,       0.000,       -0.14738934, 0.26435736,  0.000,
    0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,       0.000,
    0.000,       0.000,       0.000,       0.00};
  float dst[256] = {0};
  PackDeConvWeightFp32(in, dst, 5, 6, 2 * 2);
  EXPECT_EQ(0, CompareOutputData(dst, co, 256));
}

TEST_F(TestDeConvolutionFp32, DeConvWeightC4x4Pack2) {
  float in[] = {4.1795, 13.142, -3.593, 16.505, 19.969, -6.235, -2.380, -9.027, 23.622, 8.3608, 47.325, -14.36,
                -0.784, 37.925, -0.081, 6.1298, 37.998, 13.719, 11.029, 1.7127, 9.0560, 14.988, 3.1866, 0.0562,
                14.530, -14.10, -8.115, -8.071, 19.250, 17.923, 13.584, 3.3293, -1.514, -0.293, 18.686, 0.0873};

  float co[] = {4.1795, 13.142, -3.593, 0,      -2.380, -9.027, 23.622, 0,      -0.784, 37.925, -0.081, 0,      11.029,
                1.7127, 9.0560, 0,      14.530, -14.10, -8.115, 0,      13.584, 3.3293, -1.514, 0,      0,      0,
                0,      0,      0,      0,      0,      0,      16.505, 19.969, -6.235, 0,      8.3608, 47.325, -14.36,
                0,      6.1298, 37.998, 13.719, 0,      14.988, 3.1866, 0.0562, 0,      -8.071, 19.250, 17.923, 0,
                -0.293, 18.686, 0.0873, 0,      0,      0,      0,      0,      0,      0,      0,      0};
  float dst[64] = {0};
  PackDeConvWeightFp32(in, dst, 6, 3, 2 * 1);
  EXPECT_EQ(0, CompareOutputData(dst, co, 64));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test1) {
  float in[] = {-9.389655,  -5.83877,    7.5724425,  -1.4675674,  -2.6300175, 0, 0, 0,
                -5.456284,  0.7406984,   16.965645,  10.888806,   -7.2690716, 0, 0, 0,
                -0.8614793, -4.404605,   10.917422,  0.11158327,  11.1863365, 0, 0, 0,
                -5.2733865, -0.96367484, -4.731118,  -7.576815,   -3.4595785, 0, 0, 0,
                -6.1621623, -0.6315082,  -9.140878,  9.266748,    -8.344107,  0, 0, 0,
                13.644127,  8.206812,    7.091153,   -0.50162584, -3.792715,  0, 0, 0,
                2.0889723,  6.6916203,   -5.3981733, 11.997365,   -7.0394287, 0, 0, 0,
                -9.254076,  -5.5964484,  -5.981469,  -0.51114964, -2.7693212, 0, 0, 0};
  float bias[] = {0.7429814, 0.4863214, 0.9888875, 0.19727881, 0.009881007, 0, 0, 0};
  float __attribute__((aligned(32))) out[8] = {0};

  float no[] = {-8.646674, -4.7133026, -0.11849791, -4.530405, -5.419181, 14.387108, 2.8319538, -8.511095};
  PostConvFuncFp32C8(in, out, bias, 1, 8, 1, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 8, 0.0001));

  float relu[] = {0, 0, 0, 0, 0, 14.387108, 2.8319538, 0};
  PostConvFuncFp32C8(in, out, bias, 1, 8, 1, ActType_Relu);
  ASSERT_EQ(0, CompareOutputData(out, relu, 8, 0.0001));

  float corr_relu6[] = {0, 0, 0, 0, 0, 6, 2.8319538, 0};
  PostConvFuncFp32C8(in, out, bias, 1, 8, 1, ActType_Relu6);
  ASSERT_EQ(0, CompareOutputData(out, corr_relu6, 8, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test2) {
  float in[] = {-9.389655,  -5.83877,    7.5724425,  -1.4675674,  -2.6300175, 0, 0, 0,
                -5.456284,  0.7406984,   16.965645,  10.888806,   -7.2690716, 0, 0, 0,
                -0.8614793, -4.404605,   10.917422,  0.11158327,  11.1863365, 0, 0, 0,
                -5.2733865, -0.96367484, -4.731118,  -7.576815,   -3.4595785, 0, 0, 0,
                -6.1621623, -0.6315082,  -9.140878,  9.266748,    -8.344107,  0, 0, 0,
                13.644127,  8.206812,    7.091153,   -0.50162584, -3.792715,  0, 0, 0,
                2.0889723,  6.6916203,   -5.3981733, 11.997365,   -7.0394287, 0, 0, 0,
                -9.254076,  -5.5964484,  -5.981469,  -0.51114964, -2.7693212, 0, 0, 0};
  float bias[] = {0.7429814, 0.4863214, 0.9888875, 0.19727881, 0.009881007, 0, 0, 0};
  float __attribute__((aligned(32))) out[16] = {0};

  float no[] = {-8.646674, 0, -4.7133026, 0, -0.11849791, 0, -4.530405, 0,
                -5.419181, 0, 14.387108,  0, 2.8319538,   0, -8.511095, 0};
  PostConvFuncFp32C8(in, out, bias, 1, 8, 2, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 16, 0.0001));

  float relu[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14.387108, 0, 2.8319538, 0, 0, 0};
  PostConvFuncFp32C8(in, out, bias, 1, 8, 2, ActType_Relu);
  ASSERT_EQ(0, CompareOutputData(out, relu, 16, 0.0001));

  float corr_relu6[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 2.8319538, 0, 0, 0};
  PostConvFuncFp32C8(in, out, bias, 1, 8, 2, ActType_Relu6);
  ASSERT_EQ(0, CompareOutputData(out, corr_relu6, 16, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test3) {
  float in[] = {-9.389655,  -5.83877,    7.5724425,  -1.4675674,  -2.6300175, 0, 0, 0,
                -5.456284,  0.7406984,   16.965645,  10.888806,   -7.2690716, 0, 0, 0,
                -0.8614793, -4.404605,   10.917422,  0.11158327,  11.1863365, 0, 0, 0,
                -5.2733865, -0.96367484, -4.731118,  -7.576815,   -3.4595785, 0, 0, 0,
                -6.1621623, -0.6315082,  -9.140878,  9.266748,    -8.344107,  0, 0, 0,
                13.644127,  8.206812,    7.091153,   -0.50162584, -3.792715,  0, 0, 0,
                2.0889723,  6.6916203,   -5.3981733, 11.997365,   -7.0394287, 0, 0, 0,
                -9.254076,  -5.5964484,  -5.981469,  -0.51114964, -2.7693212, 0, 0, 0};
  float bias[] = {0.7429814, 0.4863214, 0.9888875, 0.19727881, 0.009881007, 0, 0, 0};
  float __attribute__((aligned(32))) out[24] = {0};

  float no[] = {-8.646674, -5.3524485, 8.56133,     -4.7133026, 1.2270198, 17.954533,   -0.11849791, -3.9182835,
                11.90631,  -4.530405,  -0.47735345, -3.7422307, -5.419181, -0.14518678, -8.15199,    14.387108,
                8.693133,  8.080041,   2.8319538,   7.177942,   -4.409286, -8.511095,   -5.110127,   -4.992582};
  PostConvFuncFp32C8(in, out, bias, 3, 8, 3, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 24, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test4) {
  float in[] = {-9.389655,  -5.83877,    7.5724425,  -1.4675674,  -2.6300175, 0, 0, 0,
                -5.456284,  0.7406984,   16.965645,  10.888806,   -7.2690716, 0, 0, 0,
                -0.8614793, -4.404605,   10.917422,  0.11158327,  11.1863365, 0, 0, 0,
                -5.2733865, -0.96367484, -4.731118,  -7.576815,   -3.4595785, 0, 0, 0,
                -6.1621623, -0.6315082,  -9.140878,  9.266748,    -8.344107,  0, 0, 0,
                13.644127,  8.206812,    7.091153,   -0.50162584, -3.792715,  0, 0, 0,
                2.0889723,  6.6916203,   -5.3981733, 11.997365,   -7.0394287, 0, 0, 0,
                -9.254076,  -5.5964484,  -5.981469,  -0.51114964, -2.7693212, 0, 0, 0};
  float bias[] = {0.7429814, 0.4863214, 0.9888875, 0.19727881, 0.009881007, 0, 0, 0};
  float __attribute__((aligned(32))) out[32] = {0};

  float co32[] = {0, 0, 0, 0, 0,         1.2270198, 0, 0, 0,         0,        0, 0, 0, 0, 0, 0,
                  0, 0, 0, 0, 14.387108, 8.693133,  0, 0, 2.8319538, 7.177942, 0, 0, 0, 0, 0, 0};
  PostConvFuncFp32C8(in, out, bias, 2, 8, 4, ActType_Relu);
  ASSERT_EQ(0, CompareOutputData(out, co32, 32, 0.0001));

  float co32_relu6[] = {0, 0, 6, 0, 0, 1.2270198, 6, 6, 0,         0, 6, 0.3088621, 0, 0, 0, 0,
                        0, 0, 0, 6, 6, 6,         6, 0, 2.8319538, 6, 0, 6,         0, 0, 0, 0};
  PostConvFuncFp32C8(in, out, bias, 4, 8, 4, ActType_Relu6);
  ASSERT_EQ(0, CompareOutputData(out, co32_relu6, 32, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test5) {
  float in[] = {-9.389655,  -5.83877,    7.5724425,  -1.4675674,  -2.6300175, 0, 0, 0,
                -5.456284,  0.7406984,   16.965645,  10.888806,   -7.2690716, 0, 0, 0,
                -0.8614793, -4.404605,   10.917422,  0.11158327,  11.1863365, 0, 0, 0,
                -5.2733865, -0.96367484, -4.731118,  -7.576815,   -3.4595785, 0, 0, 0,
                -6.1621623, -0.6315082,  -9.140878,  9.266748,    -8.344107,  0, 0, 0,
                13.644127,  8.206812,    7.091153,   -0.50162584, -3.792715,  0, 0, 0,
                2.0889723,  6.6916203,   -5.3981733, 11.997365,   -7.0394287, 0, 0, 0,
                -9.254076,  -5.5964484,  -5.981469,  -0.51114964, -2.7693212, 0, 0, 0};
  float bias[] = {0.7429814, 0.4863214, 0.9888875, 0.19727881, 0.009881007, 0, 0, 0};
  float __attribute__((aligned(32))) out[40] = {0};

  float no[] = {-8.646674,   -5.3524485, 8.56133,     -1.2702886, -2.6201365,  -4.7133026,  1.2270198,   17.954533,
                11.086085,   -7.2591906, -0.11849791, -3.9182835, 11.90631,    0.3088621,   11.196218,   -4.530405,
                -0.47735345, -3.7422307, -7.379536,   -3.4496975, -5.419181,   -0.14518678, -8.15199,    9.464027,
                -8.334226,   14.387108,  8.693133,    8.080041,   -0.30434704, -3.782834,   2.8319538,   7.177942,
                -4.409286,   12.194644,  -7.0295477,  -8.511095,  -5.110127,   -4.992582,   -0.31387085, -2.7594402};
  PostConvFuncFp32C8(in, out, bias, 5, 8, 5, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 40, 0.0001));

  float relu[] = {0,         0,        8.56133,  0,         0,         0,         1.2270198, 17.954533, 11.086085, 0,
                  0,         0,        11.90631, 0.3088621, 11.196218, 0,         0,         0,         0,         0,
                  0,         0,        0,        9.464027,  0,         14.387108, 8.693133,  8.080041,  0,         0,
                  2.8319538, 7.177942, 0,        12.194644, 0,         0,         0,         0,         0,         0};
  PostConvFuncFp32C8(in, out, bias, 5, 8, 5, ActType_Relu);
  ASSERT_EQ(0, CompareOutputData(out, relu, 40, 0.0001));

  float corr_relu6[] = {0, 0, 6, 0, 0, 0, 1.2270198, 6, 6, 0, 0,         0, 6, 0.3088621, 6, 0, 0, 0, 0, 0,
                        0, 0, 0, 6, 0, 6, 6,         6, 0, 0, 2.8319538, 6, 0, 6,         0, 0, 0, 0, 0, 0};
  PostConvFuncFp32C8(in, out, bias, 5, 8, 5, ActType_Relu6);
  ASSERT_EQ(0, CompareOutputData(out, corr_relu6, 40, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test6) {
  float in[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  float bias[] = {0, 0, 0, 0, 0, 0, 0, 0};
  float __attribute__((aligned(32))) out[24] = {0};

  float no_3[] = {-9.389655,  -5.83877,   7.5724425, 0, 0, 0, -0.8614793, -4.404605, 10.917422,  0, 0, 0,
                  -6.1621623, -0.6315082, -9.140878, 0, 0, 0, 2.0889723,  6.6916203, -5.3981733, 0, 0, 0};
  PostConvFuncFp32C8(in, out, bias, 3, 4, 6, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no_3, 24, 0.0001));

  float no_6[] = {-9.389655, -5.83877,   7.5724425,  -1.4675674,  -5.456284,  0.7406984,  -0.8614793, -4.404605,
                  10.917422, 0.11158327, -5.2733865, -0.96367484, -6.1621623, -0.6315082, -9.140878,  9.266748,
                  13.644127, 8.206812,   2.0889723,  6.6916203,   -5.3981733, 11.997365,  -9.254076,  -5.5964484};
  PostConvFuncFp32C8(in, out, bias, 6, 4, 6, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no_6, 24, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test7) {
  float in[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  float bias[] = {0, 0, 0, 0, 0, 0, 0, 0};
  float __attribute__((aligned(32))) out[28] = {0};

  float no[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469};
  PostConvFuncFp32C8(in, out, bias, 7, 4, 7, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 28, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test8_2) {
  float in[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  float bias[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  float __attribute__((aligned(32))) out[32] = {0};

  float no[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  PostConvFuncFp32C8(in, out, bias, 16, 2, 16, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 32, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test8_4) {
  float in[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964,
                -9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  float bias[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  float __attribute__((aligned(32))) out[64] = {0};

  float no[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  PostConvFuncFp32C8(in, out, bias, 16, 4, 16, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 64, 0.0001));
}

TEST_F(TestDeConvolutionFp32, PostConvFuncC8Test8_8) {
  float in[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964,
                -9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  float bias[] = {0, 0, 0, 0, 0, 0, 0, 0};
  float __attribute__((aligned(32))) out[64] = {0};

  float no[] = {-9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964,
                -9.389655,  -5.83877,   7.5724425,  -1.4675674, -5.456284,  0.7406984,   16.965645, 10.888806,
                -0.8614793, -4.404605,  10.917422,  0.11158327, -5.2733865, -0.96367484, -4.731118, -7.576815,
                -6.1621623, -0.6315082, -9.140878,  9.266748,   13.644127,  8.206812,    7.091153,  -0.50162584,
                2.0889723,  6.6916203,  -5.3981733, 11.997365,  -9.254076,  -5.5964484,  -5.981469, -0.51114964};
  PostConvFuncFp32C8(in, out, bias, 8, 8, 8, ActType_No);
  ASSERT_EQ(0, CompareOutputData(out, no, 64, 0.0001));
}

int DeConvTestInit1(std::vector<lite::Tensor *> *inputs_, std::vector<lite::Tensor *> *outputs_,
                    ConvParameter *conv_param, float **correct) {
  std::vector<int> in_dims_nhwc = {1, 5, 7, 2};
  auto *in_t = new lite::Tensor(kNumberTypeFloat, in_dims_nhwc, mindspore::NHWC, lite::Category::CONST_TENSOR);
  in_t->MallocData();
  float in_nchw[] = {
    0.39451003, 0.15045597,  0.5367726,   0.62690735, 0.113554195, 0.5402554,  0.5522764,  0.044319753, 0.25721782,
    0.41789535, 0.6717553,   0.72254324,  0.15164013, 0.93585724,  0.33732107, 0.14599903, 0.20070823,  0.640386,
    0.74077445, 0.088589266, 0.08755991,  0.4489046,  0.7409207,   0.7373529,  0.8887349,  0.045393247, 0.6483991,
    0.7542141,  0.8730748,   0.5480396,   0.19493233, 0.41220096,  0.77443165, 0.9909433,  0.8081086,   0.91432786,
    0.97605807, 0.48640794,  0.7690306,   0.9381521,  0.44073114,  0.27656683, 0.0725352,  0.53911537,  0.994353,
    0.2642501,  0.29840338,  0.38820496,  0.37829784, 0.105839334, 0.07713295, 0.45629853, 0.9290373,   0.56323594,
    0.59976774, 0.48325357,  0.102543674, 0.35449505, 0.3158472,   0.02927611, 0.44739273, 0.0516185,   0.12340133,
    0.13908496, 0.54970616,  0.74672216,  0.673308,   0.6400629,   0.26790652, 0.98673576}; /* nhwc */
  PackNCHWToNHWCFp32(in_nchw, in_t->MutableData(), in_t->Batch(), in_t->Width() * in_t->Height(), in_t->Channel(), 0,
                     0);
  inputs_->push_back(in_t);

  std::vector<int> weight_dims_nhwc = {2, 3, 3, 6};
  auto *weight_t = new lite::Tensor(kNumberTypeFloat, weight_dims_nhwc, mindspore::NHWC, lite::Category::CONST_TENSOR);
  weight_t->MallocData();
  float weight_nchw[] = {
    0.061163727,  -0.06261389,  0.07708351,  -0.019354159, -0.3859104,  -0.082844816, -0.21268463,  -0.15746808,
    -0.096376516, 0.016681675,  0.1364329,   -0.007941234, -0.10095563, 0.32489842,   -0.042597733, 0.2701167,
    -0.1415933,   0.007270595,  -0.34188282, -0.3374504,   -0.26375315, -0.075536035, 0.11136466,   -0.2239981,
    -0.07840504,  -0.23905717,  -0.10171707, -0.11058277,  0.363706,    -0.09807812,  -0.05729029,  0.0018888254,
    -0.29443327,  0.13365538,   0.0453783,   -0.31048688,  0.07062391,  0.16674924,   0.2268152,    -0.18341774,
    0.10190555,   0.08567296,   0.13261533,  -0.40412605,  0.13981377,  -0.08217087,  -0.050615843, -0.05403921,
    -0.028555218, 0.2651543,    0.10668221,  -0.013095176, 0.09588115,  0.044287443,  -0.009692867, 0.06717065,
    -0.29928264,  -0.09110823,  -0.07987715, -0.15888898,  0.041994736, 0.086504236,  -0.19046812,  0.20323305,
    0.08014105,   0.009099235,  0.2525443,   -0.010155359, 0.039532702, 0.20266832,   0.0045211455, -0.14146733,
    -0.07135475,  -0.011584315, 0.1640728,   0.13032198,   0.18829331,  -0.27231383,  -0.15681058,  -0.14862166,
    -0.084803745, -0.020582702, -0.0681792,  0.06789135,   0.13603394,  0.090862036,  -0.08380498,  -0.16875166,
    -0.2570391,   -0.013280135, 0.24033138,  -0.08921211,  0.2722501,   0.24916205,   -0.20001566,  -0.11610521,
    0.06060236,   0.10848369,   -0.4512424,  0.023834296,  0.1643943,   -0.25290534,  0.066953085,  -0.11685201,
    -0.4159784,   0.37839416,   -0.11141268, -0.15986018}; /* nhwc */
  PackNCHWToNHWCFp32(weight_nchw, weight_t->MutableData(), weight_t->Batch(), weight_t->Width() * weight_t->Height(),
                     weight_t->Channel(), 0, 0);
  inputs_->push_back(weight_t);

  auto *bias_t = new lite::Tensor(kNumberTypeFloat, {6}, mindspore::NHWC, lite::Category::CONST_TENSOR);
  bias_t->MallocData();
  float bias[] = {-0.19064677, -0.0034778118, 0.63741624, -1.0311537, -1.0288948, 0.71384084};
  memcpy(bias_t->MutableData(), bias, sizeof(float) * 6);
  inputs_->push_back(bias_t);

  std::vector<int> output_nhwc_dims = {1, 9, 13, 6};
  auto *out_t = new lite::Tensor(kNumberTypeFloat, output_nhwc_dims, mindspore::NHWC, lite::Category::CONST_TENSOR);
  out_t->MallocData();
  outputs_->push_back(out_t);

  *correct = reinterpret_cast<float *>(malloc(out_t->ElementsNum() * sizeof(float)));
  float nchw_co[] = {
    -0.4159262,   -0.46044537, -0.32667404,  -0.4129007,   -0.43664578,   -0.39459872, -0.49400482,   -0.4524444,
    -0.30940545,  -0.3997266,  -0.4343413,   -0.3413178,   -0.42586732,   -0.17157906, -0.4016143,    -0.1097983,
    -0.61039054,  -0.19246969, -0.6629166,   -0.24715163,  -0.36829865,   -0.1525711,  -0.50477314,   -0.22101344,
    -0.4834266,   -0.2868756,  -0.21354413,  -0.25993955,  -0.33297282,   -0.3962972,  -0.43134302,   -0.4203356,
    -0.47099167,  -0.32945585, -0.4933193,   -0.3362223,   -0.28017497,   -0.31746963, -0.5820211,    -0.2053628,
    -0.23829184,  -0.1884751,  -0.36922038,  -0.15235345,  -0.6430171,    -0.25126106, -0.63569427,   -0.28716096,
    -0.44492853,  -0.14620401, -0.63435787,  -0.27831206,  -0.32927662,   -0.24526191, -0.25315046,   -0.2604547,
    -0.30455,     -0.37681228, -0.5119872,   -0.4569657,   -0.521509,     -0.39786643, -0.27274203,   -0.33900544,
    -0.26303798,  -0.25582826, -0.22533318,  -0.2295449,   -0.2498781,    -0.20773302, -0.3777015,    -0.2648021,
    -0.50503045,  -0.23136339, -0.45421264,  -0.18984585,  -0.23228307,   -0.20156652, -0.3720746,    -0.29076657,
    -0.5048918,   -0.35140067, -0.5004279,   -0.32178527,  -0.5359573,    -0.3105652,  -0.24390095,   -0.28274524,
    -0.44499388,  -0.27840495, -0.49156278,  -0.29778862,  -0.34227157,   -0.27404356, -0.5907216,    -0.24148186,
    -0.69942933,  -0.3086446,  -0.40131485,  -0.16459012,  -0.48982328,   -0.33233505, -0.38212818,   -0.2830558,
    -0.5386851,   -0.34576517, -0.4460499,   -0.39519656,  -0.3255192,    -0.39476353, -0.40350133,   -0.4050802,
    -0.5406344,   -0.40009072, -0.5944617,   -0.42084867,  -0.58132195,   0.11541255,  0.24717134,    0.035492875,
    0.09734866,   0.16597912,  0.12381038,   0.1923936,    0.22568025,    0.023888497, 0.085535035,   0.16757454,
    0.0050217994, 0.17314728,  -0.043344263, 0.22266465,   0.057929777,   0.315026,    0.059421062,   0.3274499,
    0.02406001,   0.18286264,  0.107178226,  0.17828721,   -0.026181899,  0.23815396,  0.07757285,    0.010184985,
    0.10768472,   0.07461695,  0.21580729,   0.12219772,   0.016947635,   0.21209088,  -0.019231271,  0.22824496,
    0.060270205,  0.041847467, 0.006466368,  0.29673898,   0.04507852,    0.18171927,  -0.0113601275, 0.332155,
    0.005798064,  0.29595143,  0.0644246,    0.349865,     0.04176835,    0.20181134,  0.036958598,   0.37659368,
    -0.0836041,   0.105042435, -0.008922746, 0.04317373,   0.08832521,    0.057098098, 0.1759837,     0.19514789,
    0.07342724,   0.23147877,  0.12975746,   0.019213844,  0.1296622,     0.020062651, 0.01870161,    0.1208442,
    0.105693996,  0.20719647,  0.096077755,  0.3124894,    0.033647023,   0.26888633,  -0.06377239,   0.09272936,
    0.07928991,   0.06689171,  0.09909828,   0.14132921,   -0.0038207127, 0.23364612,  -0.015699724,  0.23287944,
    -0.10473035,  0.28497344,  0.06822525,   0.0067269485, -0.0401484,    0.20666184,  -0.074035384,  0.24031198,
    0.06368647,   0.37245232,  0.012040168,  0.3706034,    -0.020015769,  0.35215783,  -0.018986963,  0.24762997,
    0.14907081,   0.18981782,  0.061614163,  0.43125582,   0.07961907,    0.27877036,  0.048327066,   0.16899693,
    0.16380924,   0.052272163, 0.14616457,   0.12360795,   0.08904207,    0.24163374,  -0.043546468,  0.31575742,
    0.1325127,    0.24905476,  0.8535125,    0.4158996,    0.8379569,     0.36076424,  0.7887811,     0.4375921,
    0.85203487,   0.40125692,  0.8267099,    0.37313673,   0.78056836,    0.39070883,  0.750996,      0.39142087,
    0.22870147,   0.36334175,  0.22776845,   0.2842683,    0.17623127,    0.14350969,  -0.049721956,  0.22356126,
    0.21368039,   0.38709402,  0.13516903,   0.14409906,   0.6560098,     0.65856576,  0.76757306,    0.5310113,
    0.87118506,   0.25672826,  0.76198256,   0.39929584,   0.77406937,    0.43344593,  0.7274,        0.47634512,
    0.8128686,    0.50098574,  0.39502823,   0.44564128,   0.24981359,    0.31671798,  0.15317863,    0.21069425,
    0.13331234,   0.16383857,  0.28979823,   0.50662756,   0.46699578,    0.32232434,  0.6949107,     0.5320594,
    0.668199,     0.6280134,   0.745686,     0.54090333,   0.88366413,    0.25842816,  0.8259659,     0.38957846,
    0.7602142,    0.510612,    0.7381607,    0.38837627,   0.1904087,     0.33691993,  0.11685282,    0.26914072,
    -0.06617683,  0.046009183, 0.0700444,    0.356119,     0.24937916,    0.30769932,  0.06569201,    0.28872308,
    0.70671666,   0.4991707,   0.78667766,   0.36038262,   0.7790032,     0.32292485,  0.7419024,     0.48524532,
    0.7267125,    0.46316653,  0.7193444,    0.4372312,    0.7446447,     0.2186315,   0.03533274,    0.216304,
    0.25036755,   0.33977476,  0.3434924,    0.27370954,   0.16213486,    0.29132545,  0.078781545,   0.13724238,
    -0.07549429,  0.1546486,   0.7608347,    0.43421644,   0.8019545,     0.44755372,  0.7997276,     0.44701982,
    0.81010026,   0.3866497,   0.8441801,    0.24970922,   0.7982173,     0.4100442,   0.9132067,     -0.94733083,
    -1.0997784,   -0.9421829,  -1.1218354,   -0.9859438,   -1.1612623,    -0.96009386, -1.1590697,    -0.9456968,
    -1.1142067,   -0.9900875,  -1.2211759,   -1.004981,    -1.2370956,    -1.349351,   -1.2184161,    -1.1564747,
    -1.0476248,   -1.3034617,  -0.9740715,   -1.5131376,   -1.0246942,    -1.1564014,  -1.091238,     -1.2773981,
    -0.76259595,  -1.0244793,  -0.9916798,   -0.9816827,   -1.0407434,    -0.94001544, -1.2400658,    -1.0058745,
    -1.251888,    -1.0026754,  -1.2247806,   -0.99559414,  -1.1104892,    -0.9950131,  -0.93231726,   -1.1461066,
    -1.1102134,   -1.2707901,  -1.2258892,   -1.2075629,   -0.899022,     -1.2902625,  -0.8440441,    -1.3612556,
    -1.1327276,   -1.0097463,  -1.0870252,   -1.0208998,   -1.1372137,    -1.0238695,  -1.0300313,    -0.9893144,
    -1.0387962,   -0.9455299,  -1.2633826,   -0.97857773,  -1.2199508,    -0.97649026, -1.0467783,    -0.9870789,
    -0.8867735,   -1.2570912,  -0.7990466,   -1.2643247,   -0.89268696,   -1.3204725,  -0.9196508,    -1.3377675,
    -1.1563053,   -1.4048479,  -0.9489901,   -1.2825038,   -0.8854966,    -1.0209885,  -1.166144,     -0.99754405,
    -1.278291,    -1.0010624,  -1.3216578,   -1.0268149,   -1.2370203,    -0.99041694, -1.1121378,    -1.0252388,
    -1.2528121,   -1.0185167,  -0.72908103,  -1.2807931,   -0.9268043,    -1.2740122,  -1.0588918,    -1.1783062,
    -0.89433515,  -1.4704434,  -0.90606475,  -1.1208334,   -0.67285204,   -1.341852,   -0.80200857,   -1.016867,
    -1.2564906,   -0.9801711,  -1.1481711,   -0.96293676,  -1.0831497,    -0.969197,   -1.1662431,    -0.9715335,
    -1.3331397,   -1.0049394,  -1.2574395,   -0.9399705,   -1.171572,     -0.88565385, -1.2087893,    -1.1065894,
    -1.0714839,   -0.9627551,  -1.1188276,   -0.8515502,   -1.2049681,    -1.1173695,  -1.0619929,    -1.066168,
    -1.0279324,   -1.0882176,  -1.129684,    -0.9890163,   -0.8740333,    -1.2120758,  -0.56714463,   -1.1103767,
    -0.86929953,  -0.8791485,  -0.98886544,  -1.2087606,   -0.76514137,   -1.0997763,  -1.0388865,    -0.9463707,
    -1.1105144,   -0.89834666, -1.1851951,   -1.1659127,   -1.0132934,    -1.0602008,  -1.014949,     -0.9327261,
    -1.0910889,   -1.1383713,  -1.0091913,   -0.99213076,  -0.8544737,    -1.056894,   -0.94257253,   -1.0971456,
    -0.8758079,   -1.2477993,  -0.35445136,  -1.2152452,   -0.5471301,    -1.086797,   -0.73012817,   -1.3945714,
    -1.0156894,   -1.0198442,  -1.0294445,   -0.9484633,   -1.0997083,    -0.95065546, -1.1494579,    -1.0774312,
    -1.0660617,   -0.89763457, -1.13983,     -0.9865928,   -1.1166302,    -1.0880268,  -0.7381968,    -0.9876064,
    -0.5964719,   -0.9657296,  -0.74247324,  -1.041322,    -0.9059322,    -1.2995027,  -0.94108796,   -0.8961159,
    -1.0022087,   -0.89709914, -1.0036592,   -1.0499129,   -1.0242954,    -1.0631231,  -1.0169288,    -1.1581104,
    -0.94418347,  -0.853006,   -1.1137545,   -1.183017,    -0.9731438,    -1.086927,   -0.97671837,   -1.066008,
    -0.48595423,  -1.2475185,  -0.50115275,  -1.326726,    -0.5102552,    -1.3762127,  -0.39939296,   -0.9266701,
    -0.6510342,   -1.1439915,  -0.2621194,   -1.2735826,   -0.9677428,    -0.9337987,  -1.0829964,    -0.8954656,
    -1.1583862,   -1.0067348,  -1.1215614,   -1.05432,     -1.0779985,    -1.151866,   -0.98149765,   -0.8774674,
    -1.1439066,   0.71160585,  0.43664122,   0.63968056,   0.3411116,     0.79933065,  0.6023572,     0.79020524,
    0.5203902,    0.63432527,  0.34978527,   0.8055916,    0.5908885,     0.8279619,   0.6594803,     0.9234866,
    0.6951297,    0.580612,    0.8534291,    0.61968267,   0.69770944,    0.8167807,   0.6326902,     0.6108708,
    0.7726814,    0.5904738,   0.7508015,    0.71711653,   0.7171464,     0.71904653,  0.57166296,    0.70845544,
    0.3433037,    0.8610815,   0.6749295,    0.87055725,   0.6884554,     0.70868635,  0.56713784,    0.91778255,
    0.71033454,   0.8496836,   0.68372923,   0.9768204,    0.70797944,    0.5078603,   0.86912346,    0.48779017,
    0.80497104,   0.66758573,  0.7792437,    0.63723993,   0.8364369,     0.7909154,   0.7067954,     0.74354,
    0.72215,      0.7137401,   0.5893581,    0.77508205,   0.4122566,     0.8444451,   0.59620094,    0.6672466,
    0.5036563,    0.6805886,   0.72852767,   0.63650995,   0.74002045,    0.6952553,   0.6968493,     0.8008863,
    0.631564,     0.7486131,   0.79336673,   0.71474713,   0.6311797,     0.69647217,  0.6505069,     0.8208874,
    0.7216524,    0.8688757,   0.6455133,    0.87244576,   0.6376998,     0.94607174,  0.8251329,     0.6735983,
    0.51751864,   0.87973493,  0.74826664,   0.8994043,    0.72413105,    0.72747874,  0.808015,      0.6329842,
    0.8622399,    0.47823763,  0.8856161,    0.6762785,    0.73437214,    0.3766058,   0.764144,      0.60693324,
    0.89371794,   0.92908806,  0.7702812,    0.79492164,   0.58807003,    0.678272,    0.4573259,     0.7444603,
    0.49847388,   0.84439206,  0.51984715,   0.9452883,    0.7511028,     0.81281227};
  PackNCHWToNHWCFp32(nchw_co, *correct, out_t->Batch(), out_t->Width() * out_t->Height(), out_t->Channel(), 0, 0);

  conv_param->kernel_h_ = conv_param->kernel_w_ = 3;
  conv_param->stride_h_ = conv_param->stride_w_ = 2;
  conv_param->dilation_h_ = conv_param->dilation_w_ = 1;
  conv_param->pad_u_ = conv_param->pad_l_ = 1;
  conv_param->input_channel_ = in_t->Channel();
  conv_param->output_channel_ = out_t->Channel();
  conv_param->group_ = 1;
  return out_t->ElementsNum();
}

TEST_F(TestDeConvolutionFp32, DeConvTest1) {
  std::vector<lite::Tensor *> inputs_;
  std::vector<lite::Tensor *> outputs_;
  auto deconv_param = static_cast<ConvParameter *>(malloc(sizeof(ConvParameter)));
  ASSERT_NE(deconv_param, nullptr);
  memset(deconv_param, 0, sizeof(ConvParameter));
  auto *ctx = new lite::InnerContext;
  deconv_param->op_parameter_.thread_num_ = 1;
  deconv_param->op_parameter_.is_zero_shape_ = false;
  ASSERT_EQ(lite::RET_OK, ctx->Init());
  float *correct;
  int total_size = DeConvTestInit1(&inputs_, &outputs_, deconv_param, &correct);

  deconv_param->op_parameter_.type_ = PrimType_Conv2dTransposeFusion;
  kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, NHWC, PrimType_Conv2dTransposeFusion};
  auto deconv = nnacl::NNACLKernelRegistry(&deconv_param->op_parameter_, inputs_, outputs_, ctx, desc);
  ASSERT_NE(deconv, nullptr);

  int ret = deconv->Prepare();
  EXPECT_EQ(0, ret);
  ret = deconv->Run();
  EXPECT_EQ(0, ret);

  ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs_[0]->MutableData()), correct, total_size, 0.0001));
  delete deconv;
  delete ctx;
  for (auto t : inputs_) delete t;
  for (auto t : outputs_) delete t;
  free(correct);
}

int DeConvTestInit2(std::vector<lite::Tensor *> *inputs_, std::vector<lite::Tensor *> *outputs_,
                    ConvParameter *conv_param, float **correct) {
  auto *in_t = new lite::Tensor(kNumberTypeFloat, {1, 4, 2, 3}, mindspore::NHWC, lite::Category::VAR);
  in_t->MallocData();
  float in[] = {7.7566547,   19.250782, 17.923292,   13.584222, 3.3293908,  9.734102,   18.83455,  -1.5142503,
                -0.29382008, 18.686155, 0.087307654, 4.2010098, -2.2539594, 4.1795673,  13.142356, -3.5939367,
                16.505789,   19.899279, 8.556229,    19.969376, -6.2355065, -2.3804698, -9.027744, 9.5542}; /* nhwc */
  memcpy(in_t->MutableData(), in, sizeof(float) * in_t->ElementsNum());
  inputs_->push_back(in_t);

  auto *weight_t = new lite::Tensor(kNumberTypeFloat, {3, 3, 3, 2}, mindspore::NHWC, lite::Category::CONST_TENSOR);
  weight_t->MallocData();
  float weight[] = {-0.39557076, 0.15087655,  0.35216075,  -0.20893791, 0.28683448,  0.08006268,  0.9830812,
                    0.27212173,  0.5171944,   -0.0014505,  0.78694165,  0.25425306,  0.16605458,  -0.06127124,
                    0.07637237,  -0.5596424,  -0.26599348, 0.223331,    -0.45220536, -0.17021523, 0.20895825,
                    -0.07697097, 0.17581257,  0.09553282,  0.5369023,   -0.6631143,  0.51170826,  -0.5332868,
                    -0.19414032, -0.7109704,  -0.05779554, -0.05178713, 0.3592201,   -0.05532698, 0.06928781,
                    -0.5730523,  -0.21037689, -0.01435696, 0.33056936,  0.51348346,  -0.28136733, -0.36971128,
                    -0.10048455, 0.09297352,  -0.27097073, -0.08646037, -0.06631696, -0.1684566,  0.31797925,
                    -0.06270258, 0.00119315,  -0.2821196,  -0.5166795,  -0.09961014}; /* nhwc */
  memcpy(weight_t->MutableData(), weight, sizeof(float) * weight_t->ElementsNum());
  inputs_->push_back(weight_t);

  std::vector<int> out_nhwc_dims = {1, 7, 3, 2};
  auto *out_t = new lite::Tensor(kNumberTypeFloat, out_nhwc_dims, mindspore::NHWC, lite::Category::VAR);
  out_t->MallocData();
  outputs_->push_back(out_t);

  *correct = reinterpret_cast<float *>(malloc(out_t->ElementsNum() * sizeof(float))); /* nc4hw4 */
  float nchw_co[] = {9.005795,   15.341887,   6.091704,    13.748293,  -7.92756,   10.232557,  9.045886,
                     33.1299,    8.5707,      5.318199,    -14.367487, 10.22495,   -2.5882099, -0.12742424,
                     1.195263,   6.469591,    9.609164,    6.112072,   16.333368,  -4.87735,   -8.439645,
                     -11.827093, -12.340071,  -2.6368382,  -14.432123, -8.483799,  -12.28651,  0.80561405,
                     11.332421,  -0.43688506, -3.476327,   -4.587028,  -1.9491882, -3.3619316, -15.831648,
                     -10.517606, -9.204161,   -0.15148449, 1.5822954,  -10.122691, -4.7448387, 3.99177};
  PackNCHWToNHWCFp32(nchw_co, *correct, out_t->Batch(), out_t->Width() * out_t->Height(), out_t->Channel(), 0, 0);

  conv_param->kernel_h_ = conv_param->kernel_w_ = 3;
  conv_param->stride_h_ = conv_param->stride_w_ = 2;
  conv_param->dilation_h_ = conv_param->dilation_w_ = 1;
  conv_param->pad_u_ = conv_param->pad_l_ = 1;
  conv_param->input_channel_ = in_t->Channel();
  conv_param->output_channel_ = out_t->Channel();
  conv_param->group_ = 1;
  return out_t->ElementsNum();
}

TEST_F(TestDeConvolutionFp32, DeConvTest2) {
  std::vector<lite::Tensor *> inputs_;
  std::vector<lite::Tensor *> outputs_;
  auto deconv_param = static_cast<ConvParameter *>(malloc(sizeof(ConvParameter)));
  ASSERT_NE(deconv_param, nullptr);
  memset(deconv_param, 0, sizeof(ConvParameter));
  float *correct;
  int total_size = DeConvTestInit2(&inputs_, &outputs_, deconv_param, &correct);
  auto *ctx = new lite::InnerContext;
  deconv_param->op_parameter_.thread_num_ = 1;
  deconv_param->op_parameter_.is_zero_shape_ = false;
  ASSERT_EQ(lite::RET_OK, ctx->Init());

  deconv_param->op_parameter_.type_ = PrimType_Conv2dTransposeFusion;
  kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, NHWC, PrimType_Conv2dTransposeFusion};
  auto deconv = nnacl::NNACLKernelRegistry(&deconv_param->op_parameter_, inputs_, outputs_, ctx, desc);
  ASSERT_NE(deconv, nullptr);

  int ret = deconv->Prepare();
  EXPECT_EQ(0, ret);
  ret = deconv->Run();
  EXPECT_EQ(0, ret);

  ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs_[0]->MutableData()), correct, total_size, 0.0001));

  delete deconv;
  delete ctx;
  for (auto t : inputs_) delete t;
  for (auto t : outputs_) delete t;
  free(correct);
}

int DeConvTestInit3(std::vector<lite::Tensor *> *inputs_, std::vector<lite::Tensor *> *outputs_,
                    ConvParameter *conv_param, float **correct) {
  std::vector<int> in_dims_nhwc = {1, 3, 3, 2};
  auto *in_t = new lite::Tensor(kNumberTypeFloat, in_dims_nhwc, mindspore::NHWC, lite::Category::VAR);
  in_t->MallocData();
  float in_nchw[] = {0.10411751, 0.24034509, 0.71456534, 0.75286126, 0.9778457,  0.21043599,
                     0.26498786, 0.6701024,  0.9744634,  0.49075702, 0.03877404, 0.48646277,
                     0.5473929,  0.32438126, 0.87553847, 0.75820315, 0.86666644, 0.4852329};
  PackNCHWToNHWCFp32(in_nchw, reinterpret_cast<float *>(in_t->MutableData()), in_t->Batch(),
                     in_t->Width() * in_t->Height(), in_t->Channel(), 0, 0);
  inputs_->push_back(in_t);

  std::vector<int> w_dims_nhwc = {2, 2, 2, 2};
  auto *weight_t = new lite::Tensor(kNumberTypeFloat, w_dims_nhwc, mindspore::NHWC, lite::Category::CONST_TENSOR);
  weight_t->MallocData();
  float w_nchw[] = {-0.108016446, -0.44254777, 0.29249913, 0.18764605, 1.1250675,   0.29441583,
                    -0.34362152,  0.7557833,   0.16503833, 0.2418737,  -0.26612744, 0.5072577,
                    -0.4284475,   0.2215941,   0.9273913,  0.34634787};
  PackNCHWToNHWCFp32(w_nchw, weight_t->MutableData(), weight_t->Batch(), weight_t->Width() * weight_t->Height(),
                     weight_t->Channel(), 0, 0);
  inputs_->push_back(weight_t);

  std::vector<int> out_dims_nhwc = {1, 9, 9, 2};
  auto *out_t = new lite::Tensor(kNumberTypeFloat, out_dims_nhwc, mindspore::NHWC, lite::Category::VAR);
  out_t->MallocData();
  outputs_->push_back(out_t);

  *correct = reinterpret_cast<float *>(malloc(out_t->ElementsNum() * sizeof(float)));
  float nchw_co[] = {0.069747314,  0.0, 0.072624244, -0.019562019, 0.0, -0.096985765, 0.0031001933, 0.0, -0.19856673,
                     0.0,          0.0, 0.0,         0.0,          0.0, 0.0,          0.0,          0.0, 0.0,
                     -0.100149624, 0.0, 0.26847753,  0.059981894,  0.0, 0.06476824,   0.07954865,   0.0, 0.38084733,
                     0.009019416,  0.0, -0.20077711, -0.05208808,  0.0, -0.35428414,  0.12176686,   0.0, 0.11864175,
                     0.0,          0.0, 0.0,         0.0,          0.0, 0.0,          0.0,          0.0, 0.0,
                     0.074535,     0.0, 0.4189407,   0.19969228,   0.0, 0.3480338,    -0.17145246,  0.0, 0.4836111,
                     0.09650954,   0.0, 0.06611961,  0.0706511,    0.0, -0.08692852,  -0.02517605,  0.0, -0.31388155,
                     0.0,          0.0, 0.0,         0.0,          0.0, 0.0,          0.0,          0.0, 0.0,
                     -0.12426994,  0.0, 0.43432832,  -0.034639344, 0.0, 0.5653653,    0.15589589,   0.0, 0.42899233,
                     -0.0931244,   0.0, 0.1394027,   0.2537918,    0.0, 0.0793535,    0.5955104,    0.0, 0.31817663,
                     0.0,          0.0, 0.0,         0.0,          0.0, 0.0,          0.0,          0.0, 0.0,
                     0.41934675,   0.0, 0.24866292,  -0.04662904,  0.0, 0.1950781,    0.2056013,    0.0, 0.7085419,
                     0.6124906,    0.0, 0.34295332,  0.96116215,   0.0, 0.35977423,   -0.1383676,   0.0, 0.25596985,
                     0.0,          0.0, 0.0,         0.0,          0.0, 0.0,          0.0,          0.0, 0.0,
                     0.24894807,   0.0, 0.7585884,   -0.03518048,  0.0, 0.8513882,    0.73965645,   0.0, 0.46228492,
                     -0.026721025, 0.0, 0.24602996,  0.38258934,   0.0, 0.38933694,   0.88844025,   0.0, 0.3944222,
                     0.0,          0.0, 0.0,         0.0,          0.0, 0.0,          0.0,          0.0, 0.0,
                     0.6120955,    0.0, 0.46287543,  0.57347727,   0.0, 0.80662024,   0.11515418,   0.0, 0.90454257};
  PackNCHWToNHWCFp32(nchw_co, *correct, out_t->Batch(), out_t->Width() * out_t->Height(), out_t->Channel(), 0, 0);

  conv_param->kernel_h_ = conv_param->kernel_w_ = 2;
  conv_param->stride_h_ = conv_param->stride_w_ = 3;
  conv_param->dilation_h_ = conv_param->dilation_w_ = 2;
  conv_param->pad_u_ = conv_param->pad_l_ = 0;
  conv_param->input_channel_ = in_t->Channel();
  conv_param->output_channel_ = in_t->Channel();
  conv_param->group_ = 1;
  return out_t->ElementsNum();
}

TEST_F(TestDeConvolutionFp32, DeConvTest3) {
  std::vector<lite::Tensor *> inputs_;
  std::vector<lite::Tensor *> outputs_;
  auto deconv_param = static_cast<ConvParameter *>(malloc(sizeof(ConvParameter)));
  ASSERT_NE(deconv_param, nullptr);
  memset(deconv_param, 0, sizeof(ConvParameter));
  float *correct;
  int total_size = DeConvTestInit3(&inputs_, &outputs_, deconv_param, &correct);
  auto *ctx = new lite::InnerContext;
  deconv_param->op_parameter_.thread_num_ = 2;
  deconv_param->op_parameter_.is_zero_shape_ = false;
  ASSERT_EQ(lite::RET_OK, ctx->Init());

  deconv_param->op_parameter_.type_ = PrimType_Conv2dTransposeFusion;
  kernel::KernelKey desc = {kernel::KERNEL_ARCH::kCPU, kNumberTypeFloat32, NHWC, PrimType_Conv2dTransposeFusion};
  auto deconv = nnacl::NNACLKernelRegistry(&deconv_param->op_parameter_, inputs_, outputs_, ctx, desc);
  ASSERT_NE(deconv, nullptr);

  int ret = deconv->Prepare();
  EXPECT_EQ(0, ret);
  ret = deconv->Run();
  EXPECT_EQ(0, ret);

  ASSERT_EQ(0, CompareOutputData(reinterpret_cast<float *>(outputs_[0]->MutableData()), correct, total_size, 0.0001));

  delete deconv;
  delete ctx;
  for (auto t : inputs_) delete t;
  for (auto t : outputs_) delete t;
  free(correct);
}
}  // namespace mindspore
